﻿package org.kolonitsky.alexey.flashui
{
  import flash.display.MovieClip;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.geom.Point;

  public class MarkSlider extends MovieClip
  {

    /** Position minimum value **/
    public var minPos: Number = 0;
    /** Position maximum value **/
    public var maxPos: Number = 100;
    /** Defined by instance name  **/
    public var track: MovieClip;
    /** Defined by instance name **/
    public var handler: MovieClip;
    /** Defined by instance name**/
    public var mark: MovieClip
    /** Offset x **/
    private var offX: Number;
    

    public function MarkSlider() {
      super();
      stop()
      trace("Create")
      addEventListener(Event.ADDED_TO_STAGE, init)
    }
    
    private function addEventHandlers(): void {
      track.addEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox)
      track.addEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse)
      handler.addEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox)
    }
    
    private function removeEventHandlers(): void {
      track.removeEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox)
      track.removeEventListener(MouseEvent.MOUSE_WHEEL, onWhellMouse)
      handler.removeEventListener(MouseEvent.MOUSE_DOWN, onDownSlidebox)
    }
    
    private function onWhellMouse (event:MouseEvent): void {
      position += event.delta
    }
    
    public function init(event:Event): void {
      track.useHandCursor = true
      track.buttonMode = true
      handler.useHandCursor = true
      handler.buttonMode = true
    }
    
    
    private function onDownSlidebox (event:MouseEvent): void {
      if (event.target == handler)
        offX = event.localX
      else 
        offX = 0.0
      updateSliderPosition(event.localX)
      stage.addEventListener(MouseEvent.MOUSE_MOVE, onDragSlidebox)
      stage.addEventListener(MouseEvent.MOUSE_UP, onDropSlidebox)
    }
    
    
    private function onDragSlidebox (event:MouseEvent): void {
      var p: Point = track.globalToLocal(new Point(event.stageX, event.stageY))
      p.x = p.x < 0 ? 0 : p.x
      p.x = p.x > w() ? w() : p.x
      updateSliderPosition(p.x)
    }

    
    private function onDropSlidebox (event:MouseEvent): void {
      var p: Point = track.globalToLocal(new Point(event.stageX, event.stageY))
      p.x = p.x < 0 ? 0 : p.x
      p.x = p.x > w() ? w() : p.x
      updateSliderPosition(p.x)
      stage.removeEventListener(MouseEvent.MOUSE_MOVE, onDragSlidebox)
      stage.removeEventListener(MouseEvent.MOUSE_UP, onDropSlidebox)
    }

    
    protected function updateSliderPosition (xPos:Number): void {
      position = (xPos / w()) * (maxPos - minPos) + minPos
    }
    
    /** actual width of track **/
    private function w(): Number {return (track.width * track.scaleX)}


    /**
     * @property position
     * position bitween min and max
     * @default minPos
     * @see minPos
     */ 
    private var pos: Number = (maxPos - minPos) / 2

    public function get position (): Number {
      return pos
    }

    public function set position (value:Number): void {
      
      if (value < minPos) value = minPos
      if (value > maxPos) value = maxPos
      
      pos = value
      var p: Number = pos - minPos
      var d: Number = maxPos - minPos
      handler.x = track.x + (p / d) * w()
      trace("handler.x = " + handler.x + ", pos = " + p + ", distance = " + d)
      mark.scaleX = p / d
      dispatchEvent(new Event(Event.CHANGE))
    }


    /**
     * Enabled
     * @default true
     */
    private var _enabled:Boolean = true

    override public function set enabled (value:Boolean): void {
      if (_enabled == value) return
      _enabled = value
      if (_enabled) {
        track.useHandCursor = true
        handler.visible = true
        mark.visible = true
        addEventHandlers()
      } else {
        track.useHandCursor = false
        handler.visible = false
        mark.visible = false
        removeEventHandlers()
      }
    }

    override public function get enabled ():Boolean {
      return _enabled
    }

  }
}